using BepuUtilities.Memory;
using System;

namespace BepuUtilities
{
    /// <summary>
    /// 提供模拟使用的多线程调度基元、线程计数和每线程资源池。
    /// </summary>
    /// <remarks>
    /// <para>请注意,模拟不需要真正的负载平衡forloop实现。所需要的只是一种启动一些线程的方法。
    /// 所有使用多线程的系统都倾向于具有某种形式的特定于域的负载平衡,即通用线程池或用于循环实现的并行
    /// 不匹配。模拟还倾向于将调度数量保持在尽可能低的水平。加在一起,这两件事就降低了
    /// 高度优化的调度程序。</para>
    /// 当用户想要共享其他线程池,但没有时间保证极高的性能和高质量时,这一点很重要
    /// 负载均衡。与其担心这一点,他们只需包装他们碰巧有的任何实现,它可能会工作得很好。</para>
    /// </remarks>
    public interface IThreadDispatcher
    {
        /// <summary>
        /// 获取线程调度程序中可用的工作进程数。
        /// </summary>
        /// <remarks>Note that some systems (like the solver) expect the ThreadCount to be backed by truly independent threads capable of progression even when one is blocked.
        /// 如果线程计数不代表独立线程,则会发生死锁。
        /// </remarks>
        int ThreadCount { get; }

        /// <summary>
        /// 调度所有可用的工作人员。
        /// </summary>
        /// <param name="loopBody">要为每个工作进程调用的委派。</param>
        void DispatchWorkers(Action<int> workerBody);

        /// <summary>
        /// 获取与给定辅助索引关联的内存池。可以保证,在执行期间,不会有其他工人共享同一池。
        /// </summary>
        /// <remarks>All usages of the memory pool within the simulation are guaranteed to return thread pool memory before the function returns. In other words,
        /// 线程内存池用于严格意义上的临时内存,并且它永远不会被模拟保留在函数范围之外,该函数的作用域
        /// 将IThreadDispatcher作为输入。</MARKETS>
        /// <param name="workerIndex">要获取池的工作进程的索引。</param>
        /// <return>指定工作进程索引的内存池。</return>
        BufferPool GetThreadMemoryPool(int workerIndex);
    }
}
